package com.itxiao.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;

import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class HttpUtil {
    // 默认超时时间：10 秒
    private static final int DEFAULT_TIMEOUT = 20000;
    public static final String BASE_URL = "https://live-test.qianzhu8.com"; // 替换为实际域名

    public static final String LIST_ALL_CITIES = "/openApi/v1/cities/listAll";
    public static final String LIST_REGIONS_BY_CITY_ID = "/openApi/v1/cities/locateByLongitudeAndLatitude";
    public static final String  GET_CINEMA= "/openApi/v2/cinemas/pagedQuery";
    public static final String  GET_FILM = "/openApi/v1/films/pagedQuery";
    public static final String  GET_SHOW = "/openApi/v1/shows/listByCinemaAndFilm";
    public static final String  GET_SHOW_SEAT = "/openApi/v1/shows/getRealTimeSeatByShowId";
    public static final String  GET_FILM_DETAIL = "/openApi/v1/films/getById";

    /**
     * 发送 GET 请求
     *
     * @param url    请求地址
     * @param params 查询参数（可为 null）
     * @return 响应体字符串
     */
    public static String get(String url, Map<String, Object> params) {
        return request(url, params, null, Method.GET);
    }

    /**
     * 发送 POST 请求（application/json）
     *
     * @param url    请求地址
     * @param body   JSON 请求体（可为 null）
     * @return 响应体字符串
     */
    public static String postJson(String url, String body) {
        return request(url, null, body, Method.POST);
    }

    /**
     * 发送 POST 请求（form 表单）
     *
     * @param url    请求地址
     * @param params 表单参数（可为 null）
     * @return 响应体字符串
     */
    public static String postForm(String url, Map<String, Object> params) {
        return request(url, params, null, Method.POST);
    }

    /**
     * 通用请求方法（内部使用）
     *
     * @param url    请求 URL
     * @param params 查询参数或表单参数（GET/POST form 用）
     * @param body   请求体（POST JSON 用）
     * @param method 请求方法
     * @return 响应字符串
     */
    private static String request(String url, Map<String, Object> params, String body, Method method) {
        if (StrUtil.isBlank(url)) {
            throw new IllegalArgumentException("URL 不能为空");
        }

        HttpRequest request = cn.hutool.http.HttpUtil.createRequest(method, url)
                .timeout(DEFAULT_TIMEOUT)
                .setConnectionTimeout(DEFAULT_TIMEOUT)
                .setReadTimeout(DEFAULT_TIMEOUT);

        // 设置参数或请求体
        if (method == Method.GET || method == Method.DELETE) {
            if (params != null && !params.isEmpty()) {
                request.form(params); // Hutool 会自动拼接到 URL 后（GET）
            }
        } else if (method == Method.POST) {
            if (body != null) {
                // 发送 JSON
                request.body(body).contentType("application/json;charset=UTF-8");
            } else if (params != null && !params.isEmpty()) {
                // 发送 form-data 或 x-www-form-urlencoded
                request.form(params);
            }
        }

        try (HttpResponse response = request.execute()) {
            if (response.isOk()) {
                return response.body();
            } else {
                throw new RuntimeException("HTTP 请求失败，状态码: " + response.getStatus());
            }
        } catch (Exception e) {
            throw new RuntimeException("HTTP 请求异常: " + e.getMessage(), e);
        }
    }
    /**
     * 生成签名 sign
     *
     * @param params      业务参数（Map），如 name=abc, uid=10
     * @param platformId  系统参数 platformId
     * @param timestamp   系统参数 timestamp
     * @param secret      密钥 secret
     * @return 32位小写MD5签名
     */
    public static String generateSign(Map<String, Object> params, String platformId, String timestamp, String secret) {
        // 合并系统参数到参数 Map
        if (params == null) {
            params = new HashMap<>();
        }

        Map<String, Object> allParams = new HashMap<>(params);
        allParams.put("platformId", platformId);
        allParams.put("timestamp", timestamp);

        // 按参数名升序排序
        List<String> sortedKeys = new ArrayList<>(allParams.keySet());
        Collections.sort(sortedKeys);

        // 拼接 key=value&key=value...
        StringBuilder sb = new StringBuilder();
        for (String key : sortedKeys) {
            Object value = allParams.get(key);
            // null 或 "" 都转为空字符串（如 age=null → age=）
            String valStr = (value == null) ? "" : value.toString();
            sb.append(key).append("=").append(valStr).append("&");
        }

        // 移除最后一个 &
        if (sb.length() > 0) {
            sb.setLength(sb.length() - 1);
        }

        String stringA = sb.toString();
        String stringB = stringA + secret;

        return md5(stringB).toLowerCase(); // 转小写
    }

    /**
     * MD5 加密（32位大写），后续转小写
     */
    public static String md5(String content) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(content.getBytes(StandardCharsets.UTF_8));
            byte[] digest = md.digest();
            return DatatypeConverter.printHexBinary(digest); // 返回大写
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 算法不可用", e);
        }
    }
}